﻿
using One.Models;
using OneSpider.API;
using OneSpider.DbContexts;
using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OneSpider.Helper
{
    public class SpiderV2 : ISpider
    {
        private IApiService apiService;

        private OneDataContext dataContext = new OneDataContext();

        List<Tag> tags = new List<Tag>();

        public SpiderV2(IApiService apiService)
        {
            this.apiService = apiService;
        }
        
        public async Task GetAnswersAsync()
        {
            IEnumerable<Answer> answers = await apiService.GetAnswersAsync();
            DatabaseHelper<Answer>.Insert(answers);
        }

        public async Task GetArticlesAsync()
        {
            List<Article> articles = await apiService.GetArticlesAsync(0);
            if (articles == null) return;
            int length = articles.Count();
            for (int i = 0; i < length; i++)
            {
                var article = articles[i];
                if (article == null || article.Author == null) continue;
                if (!dataContext.Authors.Any(x => x.Name.Equals(article.Author.Name)))
                {
                    dataContext.Authors.Add(article.Author);
                    dataContext.SaveChanges();
                }

                Author author = dataContext.Authors.FirstOrDefault(x => x.Name.Equals(article.Author.Name));
                article.Author = author;

                for (int j = 0; j < article.Tags.Count; j++)
                {
                    var tag = article.Tags.ElementAt(j);
                    if (tag == null) continue;
                    if (!tags.Any(t=>t.Title.Equals(tag.Title)))
                    {
                        tags.Add(tag);
                        dataContext.Tags.Add(tag);
                        dataContext.SaveChanges();
                    }
                    
                    Tag _tag = dataContext.Tags.FirstOrDefault(x => x.Title.Equals(tag.Title));
                    article.Tags[j] = _tag;
                }
            }

            //try
            //{
                dataContext.Articles.AddRange(articles);
                dataContext.SaveChanges();
            //}
            //catch (DbEntityValidationException e)
            //{
            //    foreach (var eve in e.EntityValidationErrors)
            //    {
            //        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
            //            eve.Entry.Entity.GetType().Name, eve.Entry.State);
            //        foreach (var ve in eve.ValidationErrors)
            //        {
            //            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
            //                ve.PropertyName, ve.ErrorMessage);
            //        }
            //    }
            //    throw;
            //}
        }

        public async Task GetContentsAsync()
        {
            IEnumerable<Content> contents = await apiService.GetContentsAsync(0);
            DatabaseHelper<Content>.Insert(contents);
        }

        public async Task GetMoviesAsync()
        {
            List<Movie> movies = await apiService.GetMoviesAsync(0);
            int length = movies.Count();
            for (int i = 0; i < length; i++)
            {
                var movie = movies[i];
                if (!dataContext.Authors.Any(x => x.Name.Equals(movie.Author.Name)))
                {
                    dataContext.Authors.Add(movie.Author);
                    dataContext.SaveChanges();
                }

                Author author = dataContext.Authors.FirstOrDefault(x => x.Name.Equals(movie.Author.Name));
                movies.ElementAt(i).Author = author;
            }

            
            dataContext.Movies.AddRange(movies);
            dataContext.SaveChanges();
        }

        public async Task GetMusicsAsync()
        {
            List<Music> musics = await apiService.GetMusicsAsync(0);
            int length = musics.Count();
            for (int i = 0; i < length; i++)
            {
                var music = musics[i];
                if (!dataContext.Authors.Any(x => x.Name.Equals(music.Author.Name)))
                {
                    dataContext.Authors.Add(music.Author);
                    dataContext.SaveChanges();
                }

                Author author = dataContext.Authors.FirstOrDefault(x => x.Name.Equals(music.Author.Name));
                musics.ElementAt(i).Author = author;
            }

            dataContext.Musics.AddRange(musics);
            dataContext.SaveChanges();
        }

        public async Task GetSerialsAsync()
        {
            IEnumerable<Serial> serials = await apiService.GetSerialsAsync();
            DatabaseHelper<Serial>.Insert(serials);
        }

        public async Task Run()
        {
            //await GetAnswersAsync();
            await GetMoviesAsync();
            await GetArticlesAsync();
            //await GetContentsAsync();
            
            
            await GetMusicsAsync();
            
            //await GetSerialsAsync();
        }
    }
}
